package dy.com.第6六章简易聊天室.simpleServer.Server;


import dy.com.第6六章简易聊天室.simpleServer.Server.handler.ClientHandler;

import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

public class TCPServer implements ClientHandler.ClientHandlerCallback {
    private ClientListener clientListener = null;
    int listenPort;
    private List<ClientHandler> clientHandlers = new ArrayList<>();
    private final ExecutorService forwardingThreadPoolExcutor;

    public TCPServer(int listenPort) {
        this.listenPort = listenPort;
        this.forwardingThreadPoolExcutor = Executors.newSingleThreadExecutor();
    }

    void start() throws IOException {
        //先停止监听
        //stop();
        //新建监听线程
        System.out.println("启动监听线程");
        clientListener = new ClientListener(listenPort);
        clientListener.start();

    }

    //停止监听线程
    void stop() {
        if (clientListener != null) {
            clientListener.close();
            clientListener = null;
        }
        synchronized (TCPServer.this) {
            for (ClientHandler clientHandler : clientHandlers) {
                clientHandler.exit();
            }

            clientHandlers.clear();
        }
        //关闭线程池
        forwardingThreadPoolExcutor.shutdown();
    }

    public synchronized void broadcast(String str) {
        for (ClientHandler clientHandler : clientHandlers) {
            clientHandler.send(str);
        }
    }

    @Override
    public synchronized void onSelfClosed(ClientHandler clientHandler) {
        clientHandlers.remove(clientHandler);
    }

    @Override
    public void onNewMessageArrived(final ClientHandler clientHandler, final String msg) {
        System.out.println("Received-" + clientHandler.getClientInfo() + ":" + msg);
        //异步线程池
        forwardingThreadPoolExcutor.execute(() -> {
            synchronized (TCPServer.this) {
                for (ClientHandler clientHandler1 : clientHandlers) {
                    if (clientHandler1.equals(clientHandler)) {
                        continue;
                    }
                    clientHandler1.send(clientHandler.getClientInfo()+":"+msg);
                }
            }
        });
    }

    //监听线程
    private class ClientListener extends Thread {
        int listenPort;
        private ServerSocket serverSocket;
        boolean finish;

        ClientListener(int listenPort) throws IOException {
            this.listenPort = listenPort;
            finish = false;

            serverSocket = new ServerSocket(listenPort);
        }

        @Override
        public void run() {
            //新建serversocket
            System.out.println("tcp服务器监听线程正在run");


            System.out.println("tcp服务器信息:ip:" + serverSocket.getInetAddress() +
                    ",port:" + serverSocket.getLocalPort() + "，监听的端口是:" + listenPort);

            while (!finish) {
                Socket clientSocket = null;
                try {
                    clientSocket = serverSocket.accept();
                } catch (IOException e) {
                    //  e.printStackTrace();
                    continue;
                }

                try {
                    ClientHandler clientHandler = new ClientHandler(clientSocket, TCPServer.this);

                    clientHandler.readAndPrint();
                    //添加同步
                    synchronized (TCPServer.this) {
                        clientHandlers.add(clientHandler);
                    }
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }

            System.out.println("监听服务已经关闭");
        }

        private void close() {
            finish = true;
            if (serverSocket != null) {
                try {
                    serverSocket.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }


}
